package com.cloud.tsp.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloud.core.exception.MyException;
import com.cloud.core.util.R;
import com.cloud.api.domain.stats.RecordList;
import com.cloud.api.domain.sys.SystemRoleDto;
import com.cloud.api.domain.stats.QueryRecord;
import com.cloud.api.domain.tsp.QueryTrack;
import com.cloud.api.domain.tsp.VehicleLogin;
import com.cloud.api.domain.tsp.VinTimePeriod;
import com.cloud.api.constants.StrVo;
import com.cloud.mybatis.domain.TableDataInfo;
import com.cloud.tsp.mapper.VehicleLoginMapper;
import com.cloud.tsp.service.IVehicleDataService;
import com.cloud.tsp.service.IVehicleLoginService;
import org.springframework.stereotype.Service;

import jakarta.annotation.Resource;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * <p>
 * OLAP 服务实现类
 * </p>
 *
 * @author haohaibo
 * @since 2023-12-01
 */
@Service("vehicleLoginService")
public class VehicleLoginServiceImpl extends ServiceImpl<VehicleLoginMapper, VehicleLogin> implements IVehicleLoginService {


    @Resource
    private VehicleLoginMapper vehicleLoginMapper;
    @Resource
    private IVehicleDataService vehicleDataService;

    @Override
    public List<VinTimePeriod> selectVinLogin(QueryTrack para) {
        /*para.setDataScope(LoginHelper.getDataScope());
        if (para.getDataScope() == 5){
            R<SystemRoleDto> roleDetail = systemRoleOpenFeignService.getById(new StrVo(LoginHelper.getUserLogin().getRoleId()));
            String[] split = roleDetail.getData().getDeptIds().split(",");
            List<String> deptIds = new ArrayList<>(Arrays.asList(split));
            para.setDeptIds(deptIds);
        }else {
            List<String> list = new ArrayList<>();
            list.add(LoginHelper.getUserLogin().getDeptId());
            para.setDeptIds(list);
        }*/
        List<VinTimePeriod> list = vehicleLoginMapper.selectVinLogin(para);
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getEndTime() == null){
                list.get(i).setEndTime(i == list.size()-1?(LocalDateTime.now()): list.get(i+1).getStartTime());
            }
            if (i == list.size()-1){
                long days = ChronoUnit.DAYS.between(list.get(i).getStartTime(), list.get(i).getEndTime());
                if (days > 1){
                    list.get(i).setEndTime(list.get(i).getStartTime().plusDays(1));
                }
            }
        }
        return list;
    }

    @Override
    public List<VinTimePeriod> selectVinLoginTsp(QueryTrack para) {
        /*para.setDataScope(LoginHelper.getDataScope());
        if (para.getDataScope() == 5){
            R<SystemRoleDto> roleDetail = systemRoleOpenFeignService.getById(new StrVo(LoginHelper.getUserLogin().getRoleId()));
            String[] split = roleDetail.getData().getDeptIds().split(",");
            List<String> deptIds = new ArrayList<>(Arrays.asList(split));
            para.setDeptIds(deptIds);
        }else {
            List<String> list = new ArrayList<>();
            list.add(LoginHelper.getUserLogin().getDeptId());
            para.setDeptIds(list);
        }*/
        List<VinTimePeriod> list = vehicleLoginMapper.selectVinLoginTsp(para);
        /*for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getEndTime() == null){
                list.get(i).setEndTime(i == list.size()-1?(LocalDateTime.now()): list.get(i+1).getStartTime());
            }
            if (i == list.size()-1){
                long days = ChronoUnit.DAYS.between(list.get(i).getStartTime(), list.get(i).getEndTime());
                if (days > 1){
                    list.get(i).setEndTime(list.get(i).getStartTime().plusDays(1));
                }
            }
        }*/

        List<VinTimePeriod> result = new ArrayList<>();
        // 处理结束时间
        for (int i = 0; i < list.size(); i++) {
            VinTimePeriod current = list.get(i);
            if (current.getEndTime() == null) {
                // 查找后面第一个有登出时间的记录
                LocalDateTime logoutTime = null;
                for (int j = i + 1; j < list.size(); j++) {
                    if (list.get(j).getEndTime() != null) {
                        logoutTime = list.get(j).getEndTime();
                        i = j + 1;
                        break;
                    }
                }

                if (logoutTime != null) {
                    // 找到登出时间，设置为结束时间
                    current.setEndTime(logoutTime);
                    VinTimePeriod vinTimePeriod = new VinTimePeriod();
                    vinTimePeriod.setVin(current.getVin());
                    vinTimePeriod.setStartTime(current.getStartTime());
                    vinTimePeriod.setEndTime(current.getEndTime());
                    result.add(vinTimePeriod);
                } else {
                    i = list.size();
                    // 最后一条记录且未找到登出时间，设置为当天24点
                    current.setEndTime(current.getStartTime().toLocalDate().atTime(23, 59, 59));
                    VinTimePeriod vinTimePeriod = new VinTimePeriod();
                    vinTimePeriod.setVin(current.getVin());
                    vinTimePeriod.setStartTime(current.getStartTime());
                    vinTimePeriod.setEndTime(current.getEndTime());
                    result.add(vinTimePeriod);
                }
            }else {
                VinTimePeriod vinTimePeriod = new VinTimePeriod();
                vinTimePeriod.setVin(current.getVin());
                vinTimePeriod.setStartTime(current.getStartTime());
                vinTimePeriod.setEndTime(current.getEndTime());
                result.add(vinTimePeriod);
            }
        }
        System.out.println("result数据：" + result);

        //遍历每条数据，每个数据的开始时间和结束时间时间间隔小于等于五秒数据的删除
        for (int i = 0; i < result.size(); i++) {
            if (i < result.size()-1){
                long seconds = ChronoUnit.SECONDS.between(result.get(i).getStartTime(), result.get(i).getEndTime());
                if (seconds <= 5){
                    result.remove(i);
                    i--;
                }
            }
        }
        if (!result.isEmpty()){
            VinTimePeriod vinTimePeriod = new VinTimePeriod();
            vinTimePeriod.setVin(para.getVin());
            vinTimePeriod.setStartTimeDate(result.getFirst().getStartTime().toLocalDate());
            vinTimePeriod.setStartTime(result.getFirst().getStartTime());
            vinTimePeriod.setEndTime(result.getLast().getEndTime());
            long a = System.currentTimeMillis();
            List<LocalDateTime> localDateTimes = vehicleDataService.existVinDataTime(vinTimePeriod);
            long b = System.currentTimeMillis();
            System.out.println("existVinDataTime执行时间：" + (b - a) + "ms");
            Iterator<VinTimePeriod> iterator = result.iterator();
            long a1 = System.currentTimeMillis();
            while (iterator.hasNext()) {
                VinTimePeriod vinTIme = iterator.next();
                //查看localDateTimes中是否存在vinTIme开始时间和结束时间内的数据
                if (localDateTimes.stream().noneMatch(localDateTime -> localDateTime.isAfter(vinTIme.getStartTime()) && localDateTime.isBefore(vinTIme.getEndTime()))){
                    iterator.remove();
                }
            }
            if (!result.isEmpty()){
                VinTimePeriod last = result.getLast();
                if (Objects.equals(last.getEndTime(), LocalDateTime.of(last.getStartTime().toLocalDate(), LocalTime.of(23, 59, 59)))){
                    last.setEndTime(localDateTimes.getFirst());
                }
                long b1 = System.currentTimeMillis();
                System.out.println("数据处理时间：" + (b1 - a1) + "ms");
            }
        }


        return result;
    }

    @Override
    public TableDataInfo<RecordList> selectLoginRecord(QueryRecord para) {
        Page<RecordList> page = new Page<>();
        page.setCurrent(para.getPage());
        page.setSize(para.getPageSize());
        IPage<RecordList> data = vehicleLoginMapper.selectLoginRecord(page, para);
        return TableDataInfo.build(data);
    }

    @Override
    public VehicleLogin selectLoginRecordDetail(QueryRecord para) {
        VehicleLogin vehicleLogin = vehicleLoginMapper.selectLoginRecordDetail(para);
        Optional.ofNullable(vehicleLogin).orElseThrow(() -> new MyException("wds.exception.id"));
        vehicleLogin.setRecordLength(vehicleLogin.getRecord().length());
        vehicleLogin.setRecord(vehicleLogin.getRecord().toUpperCase());
        return vehicleLogin;
    }
}